package com.anan.controller;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import com.anan.annotation.CheckObject;
import com.anan.annotation.GlobalInterceptor;
import com.anan.annotation.CheckValue;
import com.anan.config.AppConfig;
import com.anan.entity.dto.UserInfoDto;
import com.anan.entity.enums.ResponseCodeEnum;
import com.anan.entity.po.UserInfo;
import com.anan.entity.query.UserInfoQuery;
import com.anan.entity.vo.UserInfoVo;
import com.anan.exception.BusinessException;
import com.anan.service.UserInfoService;
import com.anan.utils.*;
import org.apache.commons.lang3.RandomStringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URLEncoder;
import java.util.*;


/**
 * @Author: Anan
 * @email: 2328791101@qq.com
 * @project_name: anan-bookkeeping
 * @time: 2023/6/2320:41
 */

@RestController
public class MainController {
    private static final Logger logger = LoggerFactory.getLogger(MainController.class);


    @Resource
    UserInfoService userInfoService;

    @Resource
    RedisUtils<Object> redisUtils;

    @Resource
    private AppConfig appConfig;

    /**
     * 验证码 图片
     *
     * @param response
     * @throws IOException
     */
    @RequestMapping(value = "/checkCode")
    public void checkCode(HttpServletResponse response) throws IOException {
        LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(140, 40);
        String code = lineCaptcha.getCode();
        redisUtils.put(code, code, 60L);
        response.setContentType("image/jpeg");//设置相应类型,告诉浏览器输出的内容为图片
        response.setHeader("Pragma", "No-cache");//设置响应头信息，告诉浏览器不要缓存此内容
        //做浏览器兼容
        response.setHeader("Cache-Control", "no-cache");   // 设置不缓存，浏览器不会缓存验证码图片
        response.setDateHeader("Expire", 0);  // 设置有效期
        lineCaptcha.write(response.getOutputStream());

//        CreateImageCode vCode = new CreateImageCode();
//        String code = vCode.getCode();  //
//        redisUtils.put(code, code, 60);
//        response.setContentType("image/jpeg");//设置相应类型,告诉浏览器输出的内容为图片
//        response.setHeader("Pragma", "No-cache");//设置响应头信息，告诉浏览器不要缓存此内容
//        //做浏览器兼容
//        response.setHeader("Cache-Control", "no-cache");   // 设置不缓存，浏览器不会缓存验证码图片
//        response.setDateHeader("Expire", 0);  // 设置有效期
//        vCode.write(response.getOutputStream());
    }

    @RequestMapping("/login")
    @GlobalInterceptor(checkParams = true)
    public Result login(@CheckObject(required = true, checkProperties = {"userName", "password"}) @RequestBody UserInfoDto userQuery,
                        @CheckValue(required = true) String checkCode) {
        Result result = new Result();
        String checkCode1 = (String) redisUtils.get(checkCode);
        if (checkCode1 == null) {
            throw new BusinessException(ResponseCodeEnum.CODE_400);
        }
        if (checkCode1.equals(checkCode)) {
            result = userInfoService.login(userQuery);
        } else {
            result.setCode(400);
            result.setMsg(" 验证码错误!");
        }
        return result;
    }

    @RequestMapping("/register")
    public Result register(@RequestBody UserInfoDto userQuery, String checkCode) {
        Result result = new Result();
        String checkCode1 = (String) redisUtils.get(checkCode);
        if (checkCode1 == null) {
            throw new BusinessException(ResponseCodeEnum.CODE_400);
        }
        if (checkCode1.equals(checkCode)) {
            result = userInfoService.register(userQuery);
        } else {
            result.setCode(400);
            result.setMsg(" 验证码错误!");
        }
        return result;
    }

    @RequestMapping("/resetPassword")
    public Result resetPassword(@RequestBody UserInfoDto userQuery, String checkCode) {
        Result result = new Result();
        String checkCode1 = (String) redisUtils.get(checkCode);
        if (checkCode1 == null) {
            throw new BusinessException(ResponseCodeEnum.CODE_400);
        }
        if (checkCode1.equals(checkCode)) {
            result = userInfoService.resetPassword(userQuery);
            redisUtils.put("userInfo", result.getData());
        } else {
            result.setCode(400);
            result.setMsg(" 验证码错误!");
        }
        return result;
    }


    @RequestMapping("/sendCheckCode")
    public Result sendCheckCode(String email) {
        Result result = new Result();
        boolean b = userInfoService.sendCheckCode(email);
        if (b) {
            result.setCode(200);
            result.setMsg(" 用户注册邮箱验证码发送成功!");
        }
        return result;
    }


    @RequestMapping("/getAvatar")
    @GlobalInterceptor(checkLogin = false, checkParams = true)
    public void getAvatar(HttpServletResponse response, @CheckValue(required = true) String fileName) {
        response.setContentType("image/jpg");
        String projectPath = System.getProperty("user.dir");
        File filePath = new File(projectPath + "/file/");
        if (!filePath.exists()) {
            boolean mkdirs = filePath.mkdirs();
            if (!mkdirs) {
                throw new BusinessException(400, "文件文件夹创建失败  请联系管理员创建项目file文件夹");
            }
        }
        File file = new File(projectPath + "/file/" + fileName+".png");
        if (!file.exists()) {
            throw new BusinessException(400, "头像"+fileName+"文件不存在!");
        }
        try {
            FileInputStream fileInputStream = new FileInputStream(file);
            OutputStream out = response.getOutputStream();
            byte[] bytes = new byte[1024];
            int len;
            while ((len = fileInputStream.read(bytes)) != -1) {
                out.write(bytes, 0, len);
            }
            out.flush();
            out.close();
            fileInputStream.close();
        } catch (IOException e) {
            throw new BusinessException(400, "文件传输失败 请重试");
        }
    }

    @RequestMapping("/getUser")
    @GlobalInterceptor(checkLogin = true, checkParams = true)
    public Result getUser( @CheckValue(required = true) String id) {
        Result result = new Result();
        UserInfo user = userInfoService.getId(id);
        user.setPassword(null);
        result.setCode(200);
        result.setMsg("获取用户信息成功！");
        result.setData(user);
        return result;
    }


    @RequestMapping("/avatarUpload")
    @GlobalInterceptor(checkParams = true)
    public Result avatarUpload(@RequestBody MultipartFile file, @CheckValue(required = true) String userId) {
        Result result = new Result();
        String fileName = file.getOriginalFilename(); // 123.png
        String fileNameSuffix = fileName.substring(fileName.lastIndexOf("."));  // png
        String fileNamePrefix = fileName.substring(0, fileName.lastIndexOf("."));  // 123
        String filePath = System.getProperty("user.dir") + "/file/";
        if (!"jpg".equals(fileNameSuffix)) {
            try {
                // 读取图片
                BufferedImage image = ImageIO.read(file.getInputStream());
                // 创建一个新的BufferedImage，指定宽度、高度和图像类型为JPEG
                BufferedImage jpgImage = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_RGB);
                // 将PNG图片的内容绘制到新的BufferedImage上
                jpgImage.createGraphics().drawImage(image, 0, 0, null);
                // 将新的BufferedImage保存为JPG图
                ImageIO.write(jpgImage, "jpg", new File(filePath + fileNamePrefix + ".jpg"));

                String fileNameJpg = fileNamePrefix + ".jpg";
                int i = userInfoService.updateAvatar(fileNameJpg, userId);
                if (i <= 0) {
                    throw new BusinessException(400, "图片更新失败");
                }

            } catch (IOException e) {
                throw new BusinessException(400, "图片保存 失败失败" + e.getMessage());
            }
        } else {
            int i = userInfoService.updateAvatar(fileName, userId);
            if (i <= 0) {
                throw new BusinessException(400, "图片更新失败");
            }
            try {
                file.transferTo(new File(filePath + fileName));
            } catch (IOException e) {
                throw new BusinessException(400, "图片保存 失败失败" + e.getMessage());
            }
        }
        result.setCode(200);
        result.setMsg("图片保存成功!");
        return result;
    }
    

    @RequestMapping("/userList")
    @GlobalInterceptor(checkLogin = true)
    public Result userList(HttpServletRequest request){
        String token = request.getHeader("token");
        Result result = new Result();
        List<UserInfo> list = userInfoService.list();
//        String listJson = JSONArray.toJSONString(list);
        String data = null;
        try {
            data = AnanUtils.encrypt(list.toString(), token);
        } catch (Exception e) {
            e.printStackTrace();
        }
        result.setCode(200);
        result.setMsg("获取用户信息成功");
        result.setData(data);
        return result;
    }

    @RequestMapping("/userUpdate")
    @GlobalInterceptor(checkLogin = true,checkParams = true)
    public Result userUpdate(@CheckObject(required = true,checkProperties = {"id"}) @RequestBody UserInfoDto userInfoDto){
        Result result = new Result();
        UserInfoQuery userInfoQuery = new UserInfoQuery();
        BeanUtils.copyProperties(userInfoDto, userInfoQuery);
        userInfoQuery.setPassword(AnanUtils.MD5Encryption(userInfoQuery.getPassword(), userInfoQuery.getUserName()));
        int update = userInfoService.update(userInfoQuery);
        if(update <= 0){
            throw new BusinessException(400, "用户信息更新错误,错误原因可能是id错误！");
        }
        result.setMsg("用户信息更新成功");
        result.setCode(200);
        return result;
    }

    @RequestMapping("/userDelete")
    @GlobalInterceptor(checkLogin = true,checkParams = true)
    public Result userDelete(@CheckValue(required = true)String id){
        Result result = new Result();
        UserInfoQuery userInfoQuery = new UserInfoQuery();
        userInfoQuery.setId(id);
        userInfoQuery.setState(0);
        int update = userInfoService.update(userInfoQuery);
        if(update <= 0){
            throw new BusinessException(400, "用户信息更新错误");
        }
        result.setMsg("用户信息更新成功");
        result.setCode(200);
        return result;
    }


    @RequestMapping("/UploadBillFile")
    @GlobalInterceptor(checkLogin = true,checkParams = true)
    public Result UploadBillFile(@RequestBody MultipartFile file,@CheckValue(required = true) String userId) {
        Result result = null;
        try {
            File file1 = new File(System.getProperty("user.dir") + "/file/" + userId+"/");
            if(!file1.exists()){
                boolean exists = file1.mkdirs();
                if(!exists){
                    redisUtils.put(userId+"error", userId+"文件夹创建失败", 300L);
                    throw new BusinessException(400,userId+"文件夹创建失败");
                }
            }
            File file2 = new File(System.getProperty("user.dir") + "/file/" + userId + "/" + file.getOriginalFilename());
            file.transferTo(file2);
//            result = userInfoService.UploadBillFile(file2, userId);
            return result;
        } catch (IOException e) {
            redisUtils.put(userId+"error", e.getMessage(), 300L);
            throw new BusinessException(400, e.getMessage());
        }
    }

    @RequestMapping("/getUploadBillFileCode")
    @GlobalInterceptor(checkLogin = true,checkParams = true)
    public Result getUploadBillFileCode(@CheckValue(required = true)String userId){
        Result result = new Result();
        String o = (String) redisUtils.get(userId);
        if(Objects.equals(o, "200")){
            result.setCode(200);
            result.setMsg("文件上传成功");
        }else{
            result.setCode(400);
            result.setMsg(String.valueOf(redisUtils.get(userId+"error")));
        }

        return  result;
    }


}
